Skip to content

refactor(config): add shared _resolve_component utility for plugin loading#5215

Merged
aabmass merged 10 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/config-shared-resolve-component
Jun 3, 2026
Merged

refactor(config): add shared _resolve_component utility for plugin loading#5215
aabmass merged 10 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/config-shared-resolve-component

Conversation

@MikeGoldsmith
Copy link
Copy Markdown
Member

Description

Adds a shared _resolve_component() utility in _common.py that extracts the common pattern used by exporter factory functions for plugin loading.

Suggested by @lzchen in #5098.

The pattern

All three exporter factory functions (_create_span_exporter, _create_log_record_exporter, _create_push_metric_exporter) follow the same structure:

  1. Iterate a registry of built-in names → call factory with config value
  2. Check additional_properties for plugin names → load_entry_point(group, name)(**(config or {}))
  3. Raise ConfigurationError if nothing matched

The utility

def _resolve_component(config, registry, entry_point_group, component_type):
    for name, factory in registry.items():
        value = getattr(config, name, None)
        if value is not None:
            return factory(value)
    if config.additional_properties:
        name, plugin_config = next(iter(config.additional_properties.items()))
        return load_entry_point(entry_point_group, name)(**(plugin_config or {}))
    raise ConfigurationError(f"No {component_type} type specified in config.")

Tests

5 tests covering: built-in resolution, plugin loading with config, plugin with empty config, no-component error, plugin-not-found error.

Draft — this PR adds the utility and tests only. The pending exporter PR (#5128) will be updated to use it once both land. The sampler, propagator, and resource detector have enough structural differences that they don't benefit from this utility.

Extracts the common pattern used by exporter factory functions:
check built-in registry → fall back to additional_properties →
load via entry point → raise if nothing matched.

The pending exporter PR (open-telemetry#5128) will be updated to use this utility,
reducing the three near-identical factory functions to one-liners.

Assisted-by: Claude Opus 4.6
@MikeGoldsmith MikeGoldsmith marked this pull request as ready for review May 18, 2026 14:26
@MikeGoldsmith MikeGoldsmith requested a review from a team as a code owner May 18, 2026 14:26
@MikeGoldsmith MikeGoldsmith moved this to Ready for review in Python PR digest May 18, 2026
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_common.py Outdated
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_common.py Outdated
- Add _ComponentConfig Protocol declaring additional_properties contract
- Type registry as dict[str, Callable[[Any], Any]]
- Add Any return type annotation

Assisted-by: Claude Opus 4.6
…nent' into mike/config-shared-resolve-component
@MikeGoldsmith MikeGoldsmith moved this from Ready for review to Approved PRs in Python PR digest Jun 1, 2026
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_common.py
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_common.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a shared _resolve_component() helper in opentelemetry.sdk._configuration._common that abstracts the registry-then-entry-point resolution pattern used by exporter factory functions for declarative config. This is groundwork for PR #5128 (exporter plugin loading), where it will replace duplicated logic across the three signal-specific factories.

Changes:

  • Add _ComponentConfig Protocol and _resolve_component() utility to _common.py for resolving config dataclasses (with additional_properties) into component instances via either a registry of built-ins or entry-point plugin loading.
  • Add 5 unit tests covering built-in resolution, plugin loading with/without config, missing component, and missing plugin error paths.
  • Add changelog entry.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
opentelemetry-sdk/src/opentelemetry/sdk/_configuration/_common.py Adds _ComponentConfig Protocol and _resolve_component() helper
opentelemetry-sdk/tests/_configuration/test_common.py Adds TestResolveComponent with five test cases
.changelog/5215.added Changelog entry for the new shared utility

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@lzchen
Copy link
Copy Markdown
Contributor

lzchen commented Jun 1, 2026

@MikeGoldsmith

I'm a bit confused as the pr description says

The pending exporter PR (#5128) will be updated to use it once both land.

Seems like #5128 is already merged, do you plan on making a followup pr to make the exporters use the utils function?

Comment thread opentelemetry-sdk/tests/_configuration/test_common.py
@MikeGoldsmith
Copy link
Copy Markdown
Member Author

@MikeGoldsmith

I'm a bit confused as the pr description says

The pending exporter PR (#5128) will be updated to use it once both land.

Seems like #5128 is already merged, do you plan on making a followup pr to make the exporters use the utils function?

Thanks @lzchen - I think this PR was opened around the same time as the other PR and that one landed first. I don't think they had the dependency link as described. I'll update the description.

…wins

- Add docstring note explaining the JSON schema enforces exactly one
  component per config block (minProperties: 1, maxProperties: 1), and
  that "first match wins" is the defensive fallback if validation is
  bypassed
- Add test documenting that when multiple built-in fields are set,
  the first registry match wins

Assisted-by: Claude Opus 4.6
Values in additional_properties are either nested config dicts (for
**kwargs splatting) or None. Document this with a more concrete type
annotation. Note: the Protocol's instance-attribute declaration still
diverges from the generated model's ClassVar; tracked separately.

Assisted-by: Claude Opus 4.6
MikeGoldsmith and others added 2 commits June 2, 2026 14:56
…ttribute mismatch

Adds a docstring note pointing to open-telemetry#5268 which tracks reviewing the
generated additional_properties typing for stricter type checks.

Assisted-by: Claude Opus 4.6
@aabmass aabmass enabled auto-merge June 3, 2026 03:37
@aabmass aabmass added this pull request to the merge queue Jun 3, 2026
Merged via the queue into open-telemetry:main with commit 488dc4a Jun 3, 2026
479 checks passed
@github-project-automation github-project-automation Bot moved this from Approved PRs to Done in Python PR digest Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants